home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GFX Sensations 1
/
Graphic Sensations - Volume 1.iso
/
tools
/
amiga
/
gfx_card
/
opcd40.lha
/
opalpcd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-16
|
64KB
|
1,827 lines
/* opalpcd.c v0.30
program to display PhotoCD pictures and save them to OpalVision
files and display. This will read the file and convert it to a
virtual screen which may be saved in a JPEG or IFF24 file.
This program is based on hpcdtoppm by Hadmut Danisch
OH Yeah, Its going to take helluva lotta memory
base =1.5m, 4base=6meg, 16base =24m
Picked up and adapted by BAZZ on 3-2-93
I will have to use RGB toOV, and may have to break it up into
several modules to save RAM.
Additions © BAZZ 1993, and similar conditions as Hadmut states apply, that
is pass it around all you want, but dont take credit for it (unless you
add to it) and don't distribute for profit. This is intended to enrich the
Amiga community and is for educational purposes only.
I MAINTAIN HADMUT'S CONVENTION OF LEVEL 2 FILE AND MEMORY ACCESS WHICH CLOSES
OR FREES AUTOMATICALLY UPON EXIT, AND IS MORE PORTABLE CODE.
Rev .20
As of 3-8 I had resolutions up thru Base working. The decompression isnt
working right on 4Base and is being looked into. This will print out on an
OpalVision screen. The library should allown IFF24 conversion and is included
with many utilities. It might work without it but not guaranteed.
Rev .30
As of April 15, Resolution 4 is working now but takes a machine with
12 Meg of FAST Ram to load the entire picture. With 6-8 Meg fast you can
crop parts out. Unfortunately the requirement is h*w*6, and the only way
around it is radically rewriting the code. I have no incentive to do this
since I have enough memory, and resolution 5 (3072x2048) isn't working yet.
doing a 'dummy test' found that none of the compression beyond the first
Luma compression worked. When this works, I'll consider it.
The Overview mode is fixed now and shows 16 small pictures on a page.
Pressing right button goes to next page, and pressing left exits. When
the top is reached it cycles back to the first page.
Also fixed a bug that left Opal screen open if an error is encountered.
Rev .40
May 12, 1993
Allows start of slideshow( -p) mode anywhere. Slideshow keeps repeating
until mouse held down. When last picture is shown it goes back to first
Uses virtul memory sort of.
For resolutions 4 and 5, option -v allows
loading and most conversion then storing to hard disk. Memory is freed and
then reloaded in small bits to the Opalvision screen which now has the
lion's share of memory available. Adds a few seconds, but is the ONLY way
most can use resolution 5.
This was compiled using SAS/C® V 6.02
*/
/* hpcdtoppm (Hadmut's pcdtoppm) v0.1
* Copyright (c) 1992 by Hadmut Danisch (danisch@ira.uka.de).
* Permission to use and distribute this software and its
* documentation for noncommercial use and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation. It is not allowed to sell this software in
* any way. This software is not public domain.
Here it is. This file IS supporting documentation -BAZZ
*/
#define xDEBUG
/* extern char *malloc(); */
#include <proto/all.h>
#include <opal/opallib.h>
#include <graphics/gfxbase.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <String.h>
#include <dos.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <libraries/asl.h>
#include <exec/execbase.h>
#include <graphics/gfxmacros.h>
#include <hardware/custom.h>
#
#include <devices/timer.h>
#include <workbench/startup.h>
#include <time.h>
#include <math.h> /* lets give it something to REALLY Render */
#include <m68881.h> /* use co pro wherever possible */
typedef unsigned long dim;
#define BaseW ((dim)768)
#define BaseH ((dim)512)
#define DISP_W 736
#define DISP_H 476 /* hi-res screen */
#define slen 3072 /* try to keep all defines here! */
#define SECSIZE 0x800 /* 2k for CDrom */
#define RBMASK 0x0400
#define ASKIP { argc--; argv ++;}
#define ABACK { argc++; argv --;} /* added incase we have something wrong */
#define SeHead 2
#define L_Head (1+SeHead)
#define SeBase16 18
#define L_Base16 (1+SeBase16)
#define SeBase4 72
#define L_Base4 (1+SeBase4)
#define SeBase 288
#define L_Base (1+SeBase)
#define S_DEFAULT S_Base /* default to base */
#define VERS 40 /* current version */
#define VLINES 32 /* number of lines to pull in at once for virt memory */
enum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF,
E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,
E_IMP,E_COOL,E_OVD,E_SCR,E_NCDS,E_ABT };
enum TURNS { T_NONE,T_RIGHT,T_LEFT };
enum SIZES { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,
S_4BaseHC, S_Over, };
/* Default taken when no size parameter given */
char *lumfn="OpcdLuma.tmp"; /* filenames for working files */
char *c1fn= "OpcdChr1.tmp";
char *c2fn= "OpcdChr2.tmp";
struct ph1 /* the header for the Photo CD file */
{char id1[8];
char ww1[14];
char id2[20];
char id3[4*16+4];
short ww2;
char id4[20];
char ww3[2*16+1];
char id5[4*16];
char idx[11*16];
} ;
struct ifhdr{ /* structure header for header */
ULONG type; /* should be OPif */
ULONG plane;/* should be LUMA, CHR1, or CHR2 */
USHORT width; /* typ 1536 */
USHORT height;/* typ 1024 */
USHORT vers;
USHORT misc; };
struct ifhdr ih={ 0x4F506966,0x4B554C41,1536,1024,40,0}; /* default */
struct _implane
{dim mwidth,mheight, iwidth,iheight;
byte *im;
};
typedef struct _implane implane;
/* PROTOTYPES */
void getout(void), cleanup(enum ERRORS);
void telltime(char *, unsigned int *);
int Display_Mode_Check(void);
int DoOpal(int,int, char *fname),VirtOpal(int,char *);
int GetNextPic(int,int);
int TurnOpal( struct OpalScreen *, UBYTE **, int,int,int,int,int);
struct OpalScreen *OpenOpal(void);
static void planealloc(implane *,dim,dim);
static void interpolate(implane *);
static void ycctorgb(dim,dim, implane *,implane *,implane *);
static void readhqt(dim,dim,dim);
static void readhqtsub(struct pcdhqt *source,struct myhqt *ziel,int *anzahl);
static void decompress(dim,dim,implane *,implane *, implane *);
static void clear(implane *,int);
static void druckeid(void );
static void sharpit(implane *);
int storeplane(implane *,char *); /* save it */
void planefree(implane *); /* free contents of a plane */
enum ERRORS readplain(dim,dim,implane *,implane *,implane*);
/* Global Variables */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct OpalBase *OpalBase;
struct OpalScreen *OScrn;
struct WBArg *WBArg;
BOOL FromWB;
__far UBYTE *Button = (UBYTE *)0xbfe001; /* Nasty */
__far UWORD *RButton= (UWORD *)0xdff016; /* read right button */
__far extern struct Custom custom; /* for registers */
/* bit 10, use dff016 for right */
#define RIGHT custom.joy1dat & 2
#define LEFT custom.joy1dat & 0x200
#define UP ( custom.joy1dat & 1 )
#define DOWN ( custom.joy1dat & 0x100)
#define FIRE (*Button & 0x80)
static FILE *fin=0,*fout=0;
static char *pcdname=0,*ppmname=0;
static char nbuf[100];
static byte sbuffer[SECSIZE]; /* Increase, allow for reading 2 sectors */
static byte sbufaux[SECSIZE];
static byte lumadump[3100]; /* for null char for mode 6 */
static int do_sharp,backdrop,crop,virt;
static int init;
implane Luma, Chroma1,Chroma2,C1t,C2t; /* make them global */
dim w,h;
static int version,cropx,cropw,cropy,croph,jpeg; /* coords for cropping */
int pstart;
unsigned int clock1[2],clock2[2]; /* for timer */
enum TURNS turn=T_NONE;
/* Using preprocessor for inline-procs */
#ifdef DEBUG
#define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) cleanup(E_READ);\
fprintf(stderr,"S-Position %x\n",ftell(fin)); }
#else
#define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) cleanup(E_READ);}
#endif
#define SKIP(n) { if (fseek(fin,(n),1)) cleanup(E_READ);}
#define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
#define READBUF fread(sbuffer,sizeof(sbuffer),1,fin)
#define READ2BUF fread(sbuffer,sizeof(sbuffer),2,fin) /* allow for 2 sectors or 4K */
#define TRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b) ))
#define NORM(x) x=TRIF(x,0,255,0,x,255)
void getout()
{
cleanup(E_ABT);
} /* just to get out, this is the ^C trap */
void cleanup(e) /* leave and display why */
enum ERRORS e;
{
switch(e)
{case E_NONE: return;
case E_IMP: fprintf(stderr,"Sorry, Not yet implemented.\n"); break;
case E_READ: fprintf(stderr,"Error while reading.\n"); break;
case E_WRITE: fprintf(stderr,"Error while writing.\n"); break;
case E_INTERN: fprintf(stderr,"Internal error.\n"); break;
case E_ARG: fprintf(stderr,"Arguments !\n");
fprintf(stderr,"OpalPCD Access for Amiga V. %d \n",VERS);
fprintf(stderr,"Usage: opalpcd [options] pcd-file [IFF24file]\n");
fprintf(stderr,"Opts:\n");
fprintf(stderr," -i Give some (buggy) informations from fileheader\n");
fprintf(stderr," -s Apply simple sharpness-operator on the Luma-channel\n");
fprintf(stderr," -d Show differential picture only \n");
fprintf(stderr," -r Rotate clockwise for portraits\n");
fprintf(stderr," -l Rotate counter-clockwise for portraits\n");
fprintf(stderr," -a Enable AutoSync for Opal Display \n");
fprintf(stderr," -p Presentation SLideShow all Images in cd0:\n");
fprintf(stderr," -b To place image as backdrop upon exit \n");
fprintf(stderr," -c x y [w] [h] crop output image. \n");
fprintf(stderr," where x,y =coords of upper left. w&h are size\n");
fprintf(stderr," -j [quality] Save in Jpeg instead of IFF24 \n");
fprintf(stderr," -v virtual mem. Uses H Drive Modes 4&up only \n");
fprintf(stderr," -O Extract thumbnails from Overview file\n");
fprintf(stderr," -1 Extract 128x192 from Image file\n");
fprintf(stderr," -2 Extract 256x384 from Image file\n");
fprintf(stderr," -3 Extract 512x768 from Image file\n");
fprintf(stderr," -4 Extract 1024x1536 from Image file\n");
fprintf(stderr," -5 Extract 2048x3072 from Image file\n");
fprintf(stderr," -6 Extract 1024X1536 Enhanced Chroma\n");
break;
case E_OPT: fprintf(stderr,"These Options are not allowed together.\n");break;
case E_MEM: fprintf(stderr,"Not enough memory !\n"); break;
case E_HUFF: fprintf(stderr,"Error in Huffman-Code-Table\n"); break;
case E_SEQ: fprintf(stderr,"Error in Huffman-Sequence\n"); break;
case E_SEQ1: fprintf(stderr,"Error1 in Huffman-Seque nce\n"); break;
case E_SEQ2: fprintf(stderr,"Error2 in Huffman-Sequence\n"); break;
case E_SEQ3: fprintf(stderr,"Error3 in Huffman-Sequence\n"); break;
case E_SEQ4: fprintf(stderr,"Error4 in Huffman-Sequence\n"); break;
case E_SEQ5: fprintf(stderr,"Error5 in Huffman-Sequence\n"); break;
case E_SEQ6: fprintf(stderr,"Error6 in Huffman-Sequence\n"); break;
case E_SEQ7: fprintf(stderr,"Error7 in Huffman-Sequence\n"); break;
case E_POS: fprintf(stderr,"Error in file-position\n"); break;
case E_COOL: fprintf(stderr,"Cannot opan opal.library \n"); break;
case E_OVD: fprintf(stderr,"Opalvision error \n"); break;
case E_SCR: fprintf(stderr,"You need a 15KHZ scan rate(genlockable) screen \n"); break;
case E_NCDS: fprintf(stderr," Slide Show available in Base/4 and Base Only \n"); break;
case E_ABT: fprintf(stderr," User Aborted with CTRL-C \n");
default: fprintf(stderr,"Unknown error %d ???\n",e);break;
}
if(fin) fclose(fin); /* close files */
if(fout) fclose(fout);
if (OpalBase!=NULL) /* if we did play with OpalVision, lets fix things */
{ AmigaPriority();
if (OScrn) FreeScreen24 (OScrn); /* oops, forgot */
CloseScreen24 ();
CloseLibrary ((struct Library *)OpalBase);
}
exit(e); /* return the error */
}
static void planealloc(p,width,height)
implane *p;
dim width,height;
{
p->iwidth=p->iheight=0;
p->mwidth=width;
p->mheight=height;
/* this is level II and freed by c startup, we should fix later */
p->im = ( byte * ) malloc (width*height);/* we know a byte is 1! */
if(!(p->im)) cleanup(E_MEM);
}
void planefree(implane *p) /* simply free the plane added 5/6/93 */
{
if ( p->im) free(p->im); /* that's it! */
}
main(argc,argv) /* MAIN */
int argc;
char **argv;
{int i,bildnr;
char *opt;
int do_auto,cd_offset,do_info,do_diff,do_overskip,do_slide;
int cccnt=0,Err,a,orun=0;
enum SIZES size=S_UNSPEC;
UBYTE *rgbps[3];
enum ERRORS eret;
pstart=1; /* normally start at 1 */
ih.vers=VERS; /* current version */
do_info=do_auto=do_diff=do_overskip=do_sharp=0;
backdrop=do_slide=crop=jpeg=virt=0; /* default to 0 */
Luma.im=Chroma1.im=Chroma2.im = NULL;
ASKIP;
init=0;
onbreak(getout); /* try to set a ctrl c trap */
/* parse input line */
cropx=cropy=-1; /* default meaning not set */
cropw=DISP_W; croph=DISP_H; /* default to one full screen */
while((argc>0) && (**argv=='-')) {
opt= (*argv)+1;
ASKIP
/* don't screw with anything between the while and this comment */
if(!strcmp(opt,"c")) /* crop coordinates */
{ /* now fetch coords */
crop=255;
if( isdigit( **argv) && (argc >0)) { /* see if following is a # */
cropx=atoi(*argv); cccnt++;
ASKIP
if(isdigit(**argv) && argc ){ /* look for cropy */
cropy=atoi(*argv); cccnt++;
ASKIP
if(isdigit(**argv) && argc ){ /* look for cropw */
cropw=atoi(*argv); cccnt++;
ASKIP
if(isdigit(**argv)&&argc ){ /* look for croph */
croph=atoi(*argv); cccnt++;
ASKIP;
/* we got all four if we got here */
}
else { cropw=DISP_W; } /* cant use w w/o h*/
}
}
else { cropx= -1; }
}
/* couldnt get cropx */
printf( "cropping left = %d top = %d width = %d height =%d\n",cropx,cropy,cropw,croph);
continue;
}
if(!strcmp(opt,"j")) /* select jpeg file mode */
{
if (isdigit ( **argv) && (**argv != '-')&&(argc>0)) {
/* look for quality factor */
jpeg=atoi(*argv);
ASKIP
}
else { jpeg = 84; } /* assume 84 if not spec */
if (jpeg <1 ) jpeg=1;
if (jpeg >100) jpeg=100;
continue;
}
/* printf("past my options %d \n",argc); */
if(!strcmp(opt,"a")) /* slide show mode */
{if (!do_auto ) do_auto=255;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"p")) /* slide show mode */
{if (!do_slide ) do_slide=255;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"v")) /* Virtual memory mode, size 4 and up please! */
{if (!virt ) virt=255;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"r"))
{if (turn == T_NONE) turn=T_RIGHT;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"l"))
{if (turn == T_NONE) turn=T_LEFT;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"i"))
{ if (!do_info) do_info=1;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"d"))
{ if (!do_diff) do_diff=1;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"b"))
{ if (!backdrop) backdrop=1;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"s"))
{ if (!do_sharp) do_sharp=1;
else cleanup(E_ARG);
continue;
}
if(!strcmp(opt,"x"))
{ if (!do_overskip) do_overskip=1;
else cleanup(E_ARG);
continue;
}
/* get desired size */
if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1")) || (!strcmp(opt,"128x192")))
{ if (size == S_UNSPEC) size = S_Base16;
else cleanup(E_ARG);
continue;
}
if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2")) || (!strcmp(opt,"256x384")))
{ if (size == S_UNSPEC) size = S_Base4;
else cleanup(E_ARG);
continue;
}
if((!strcmp(opt,"Base" )) || (!strcmp(opt,"3")) || (!strcmp(opt,"512x768")))
{ if (size == S_UNSPEC) size = S_Base;
else cleanup(E_ARG);
continue;
}
if((!strcmp(opt,"4Base" )) || (!strcmp(opt,"4")) || (!strcmp(opt,"1024x1536")))
{ if (size == S_UNSPEC) size = S_4Base;
else cleanup(E_ARG);
continue;
}
if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5")) || (!strcmp(opt,"2048x3072")))
{ if (size == S_UNSPEC) size = S_16Base;
else cleanup(E_ARG);
continue;
}
if( (!strcmp(opt,"4BC" )) || (!strcmp(opt,"6")) )
{ if (size == S_UNSPEC) size = S_4BaseHC;
else cleanup(E_ARG);
continue;
}
if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0")) || (!strcmp(opt,"O")))
{ if (size == S_UNSPEC) size = S_Over;
else cleanup(E_ARG);
continue;
}
fprintf(stderr,"Unknown option: -%s\n",opt);
cleanup(E_ARG);
}
/* printf( "loop completed \n");*/
if(size==S_UNSPEC) size=S_DEFAULT;
if((argc<1) && !(do_slide)) cleanup(E_ARG); /* forgive lack of name if slide */
pcdname= *argv;
ASKIP;
if(argc>0)
{ppmname= *argv;
ASKIP;
}
if ( isdigit(*pcdname) && isdigit ( *(pcdname+1) ) && (strlen(pcdname)==2))
{ /*two digit number, use as easy file name */
pstart= (*pcdname - 48)*10 ;
pstart+=( *(pcdname+1) -48);
printf("starting at %d \n",pstart);
strcpy(nbuf,"CD0:PHOTO_CD/IMAGES/IMG00"); /* build name */
strcat(nbuf,pcdname);
strcat(nbuf,".PCD");
pcdname=nbuf; /* transfer pointer */
if (size == S_Over) pcdname ="CD0:PHOTO_CD/OVERVIEW.PCD";
/* for an overview, use this file 4-15-93 */
}
if(argc>3) cleanup(E_ARG);
/* if((size==S_Over) && (!ppmname)) cleanup(E_ARG); */
if(do_info && (size==S_Over)) cleanup(E_OPT);
if(do_diff && (size != S_4Base) && (size != S_16Base)&& (size != S_4BaseHC)) cleanup(E_OPT);
if(do_overskip) cleanup(E_IMP);
if(do_overskip && (size != S_Base4) && (size != S_Base16)) cleanup(E_OPT);
if(do_slide) { /* for auto */
ppmname=NULL; /* we wont save file */
if(!(pcdname))
pcdname="CD0:PHOTO_CD/IMAGES/IMG0001.PCD";
/* start at beginning if not spec */
if (size > S_Base) {
printf( "can't slideshow above base res \n");
cleanup(E_ARG); }
}
/* printf( " infile %s jpeg %d slide %d argc %d \n",pcdname,jpeg,do_slide,argc);
*/
#ifdef DEBUG
fprintf(stderr,"Turn %d Size %d Pcd %s ppm %s\n",turn,size,pcdname,ppmname);
#endif
if(!(fin=fopen(pcdname,"r"))) cleanup(E_READ);
if(do_info) druckeid(); /* show ID code */
OpalBase = (struct OpalBase *) OpenLibrary ("opal.library",0L);
if (OpalBase==0L) /* opal opal library */
cleanup (E_COOL);
OScrn = NULL;
i=timer(clock1); /* get clock */
switch(size) /* perform the operation based on size */
{
case S_Base16: w=BaseW/4;
h=BaseH/4;
if (do_slide) cleanup( E_NCDS);
planealloc(&Luma ,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
SEEK(L_Head+1);
cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
/* writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);*/
OpenOpal();
DoOpal(do_auto,do_slide,ppmname);
break;
case S_Base4: w=BaseW/2;
h=BaseH/2;
planealloc(&Luma ,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
SEEK(L_Head+L_Base16+1);
cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
OpenOpal();
DoOpal(do_auto,do_slide,ppmname);
break;
case S_Base: w=BaseW;
h=BaseH;
planealloc(&Luma ,w,h);
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
if (!OpenOpal()) cleanup(E_OVD);
SEEK(L_Head+L_Base16+L_Base4+1);
cleanup(readplain(w,h,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
DoOpal( do_auto,do_slide,ppmname); /* do all the nice OpalVision stuff */
break;
case S_4BaseHC:
case S_4Base: w=BaseW*2;
h=BaseH*2;
if (do_slide) cleanup( E_NCDS);
planealloc(&Luma,w,h); /* thats almost 5 meg! */
planealloc(&Chroma1,w,h);
planealloc(&Chroma2,w,h);
if ( !virt){ /* open it here if NOT virtual mem */
if (!OpenOpal()) {
printf("Can't open Opal Screen. Try a smaller area \n");
cleanup(E_OVD); }
}
SEEK(L_Head+L_Base16+L_Base4+1);
/* THIS IS ONLY THE SAME AS MODE 3! */
cleanup(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
interpolate(&Luma);
interpolate(&Chroma1);
interpolate(&Chroma1);
interpolate(&Chroma2);
interpolate(&Chroma2);
if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
/* above only clears */
cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
SEEK(cd_offset + 4); readhqt(w,h,1);
SEEK(cd_offset + 5);
decompress(w,h,&Luma,0,0);
/* add full LUMA res */
if (size== S_4BaseHC) { /* we are trying to fill colors*/
cd_offset=ftell(fin);
if(cd_offset % SECSIZE) cleanup(E_POS);
cd_offset/=SECSIZE;
SEEK(cd_offset+12);
readhqt(w*2,h*2,3);
printf(" gonna decomp the chroma now\n");
SEEK(cd_offset+14);
decompress(w*2,h*2,0,&Chroma1,&Chroma2);
/* try adding full chroma from highest sampling */
}
if (virt) { /* do this if using virtual mem */
printf("Virtual memory mode selected, now saving \n");
ih.width=w; ih.height=h;
i=storeplane(&Luma,lumfn); /* store Luma plane*/
planefree(&Luma); /* free it up */
if (i) { printf("Error %d storing intermediate file, too little disk space? \n",i);
cleanup(E_WRITE); }
i=storeplane(&Chroma1,c1fn);
planefree(&Chroma1);
i=storeplane(&Chroma2,c2fn);
planefree(&Chroma2);
if (i) { printf("Error %d storing intermediate file, too little disk space? \n",i);
cleanup(E_WRITE); }
if (!OpenOpal()) {
printf("Can't open Opal Screen. Try a smaller area \n");
cleanup(E_OVD);
}
VirtOpal(do_auto,ppmname);
}
else { ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
/* normal mode, do all in one swell foop. Needs 12M fast*/
telltime("Time to Decode Picture:",clock1);
DoOpal( do_auto,do_slide,ppmname); /* try disp some */
}
break;
case S_16Base: w=BaseW*4;
h=BaseH*4;
if (do_slide) cleanup( E_NCDS);
planealloc(&Luma,w,h);/* full luma no matter what */
SEEK(L_Head+L_Base16+L_Base4+1);
if (virt){ /* Virt Mem. Just alloc enuf chroma to read PCD!*/
planealloc(&C1t,w/8,h/8);/* just get the data for now */
planealloc(&C2t,w/8,h/8);/* theyre only 98K each */
cleanup(readplain(w/4,h/4,&Luma,&C1t,&C2t));
}
else {planealloc(&Chroma1,w,h);/* normal, got 20-40Meg??*/
planealloc(&Chroma2,w,h);
OpenOpal();
cleanup(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
interpolate(&Chroma1);
interpolate(&Chroma1);
interpolate(&Chroma2);
interpolate(&Chroma2); /* expand chroma */
}
interpolate(&Luma); /* expand luma to 1536x1024 */
cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
SEEK(cd_offset + 4);
readhqt(w/2,h/2,1);
SEEK(cd_offset + 5);
decompress(w/2,h/2,&Luma,0,0); /* decomp luma to 1536x1024*/
interpolate(&Luma); /* spread Luma to 3072x2048 */
cd_offset=ftell(fin);
if(cd_offset % SECSIZE) cleanup(E_POS);
cd_offset/=SECSIZE;
SEEK(cd_offset+12);
readhqt(w,h,3);
if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
SEEK(cd_offset+14); /* we are in position for final decomp */
if (virt) { /* Again, do this in virtual mode */
/* takes about 10 Meg of HD space */
ih.width=w; ih.height=h; /* store size */
printf("Virtual memory selected, saving Mode 5 Luma \n");
decompress(w,h,&Luma,&Chroma1,&Chroma2);/* decomp the final Luma */
/* CODE MOVED TO DECOMPRESS TO STORE LUMA AND SETUP CHROMA PLANES */
/* THIS BECAUSE DECOMPRESS IS NOT TOO REENTRANT AND I DONT WANT TO F*** WITH IT*/
/* at this point, we should have two 1536x1024 chroma planes
unless we got a huffman error, etc */
ih.width=w/2; ih.height=h/2; /* chroma planes 1/4 size*/
i=storeplane(&Chroma1,c1fn);
planefree(&Chroma1);/* store and free them */
i=storeplane(&Chroma2,c2fn);
planefree(&Chroma2);
if (i) { printf("Error %d storing intermediate file, too little disk space? \n",i);
cleanup(E_WRITE); }
if (!OpenOpal()) {
printf("Can't open Opal Screen. Try a smaller area \n");
cleanup(E_OVD);
}
/* NOTE: WE WILL DO FINAL INTERPOLATION OF CHROMA WHEN
WE LOAD IT BACK IN. This saves 9M HD+Xfer time */
VirtOpal(do_auto,ppmname);
}
else { /* 'Normal' Mode, that is, if you own Samsung Memory division */
decompress(w,h,&Luma,0,0);
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
DoOpal(do_auto,0,ppmname); /* display what we can */
}
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
break;
case S_Over: /* we are going to render some small images */
w=BaseW;
h=BaseH; /* use a full size screen for now */
planealloc(&Luma ,w/4,h/4); /* allocate for tiny images */
planealloc(&Chroma1,w/4,h/4);
planealloc(&Chroma2,w/4,h/4);
if( !(Chroma2.im) ) cleanup(E_MEM);
rgbps[0]=Luma.im;
rgbps[1]=Chroma1.im; /* copy pointers */
rgbps[2]=Chroma2.im;
if (!( OpenOpal())) cleanup(E_OVD);
OScrn->Pen_R=OScrn->Pen_G=0;
OScrn->Pen_B=100; /* blue background */
for(orun=0; orun <8 && !feof(fin); orun++){ /* loop each page (16 pix) */
SetScreen24(OScrn); /* clear and install bkgrnd */
for(bildnr=orun<<4;!feof(fin) && (bildnr< (orun+1)<<4);bildnr++){ /* ea pic*/
SEEK(5+SeBase16*bildnr);
eret=readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2);
if(eret==E_READ) break;
cleanup(eret);
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w/4,h/4,&Luma,&Chroma1,&Chroma2);
/* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
RGBtoOV(OScrn,rgbps,(bildnr&3)*190,((bildnr>>2)&3)*120,192,128);
/* render each of 16 in */
}
AutoSync24(do_auto);
Err = (long)LowMemUpdate24 (OScrn,0);
if ((Err>OL_ERR_MAXERR) && (!(OScrn->Flags&ILACE24)))
{ AutoSync24 (do_auto);
/* Err = (long)LowMemUpdate24 (OScrn,6); */
}
/* end of main loop. If we save img, save last image */
while ( ( *Button &0x040) &&(*RButton & RBMASK) ){ /* button for single show */
Delay(10); } /* if no button down wait */
if (!(*RButton & RBMASK)){ /* right pushed */
/* next page and continue */
if ( feof(fin) ){ orun=-1; /* if we hit end of pix, start anew */
rewind(fin); /* set position back to start */
Delay(5); }
}
else orun=20; /* put loop var high to exit, was left mouse button */
} /* end of running loop, past here were done */
if ( (OScrn) && (ppmname) ){ /* we can save file */
if (jpeg)
a=SaveJPEG24(OScrn,ppmname,NULL, jpeg);
else
a=SaveIFF24(OScrn,ppmname, NULL,NULL);
if (a) printf( "iff save error # %d couldn't save picture\n",a);
else printf( "file saved as %s \n",ppmname);
}
if ( backdrop){ /* we want to leave image as backdrop */
AmigaPriority ();
DualDisplay24 ();
Delay (2L);
LatchDisplay24 (TRUE);
Delay (2L);
}
FreeScreen24 (OScrn); /* clean up here */
CloseScreen24();
return(0);
break;
default: cleanup(E_INTERN);
}
/* WE USE LEVEL 2 FILE&MEM HANDLING, IF WE FORGET TO FREE OR CLOSE, NO HARM DONE*/
exit(0); /* exit normal */
}
#undef ASKIP
struct OpalScreen *OpenOpal() /* display and save OV */
/* This just appropriats and opens the Opal Screen */
{
long scm;
int dw,dh;
scm= OVERSCAN24;
if (!Display_Mode_Check())
cleanup( E_SCR); /* check for 15KHZ res */
dw= DISP_W/2; dh=DISP_H/2;
if ( w> 400) {
scm |= ILACE24 | HIRES24; /* if base & up do hires lace */
dw=DISP_W; dh=DISP_H;
if ( !crop) cropx=cropy=0;
}
else {
cropx= (dw-w+2)/2; /* center picture tiny res no crop possible */
cropy= (dh-h+2)/2;
}
if ( !crop ) {
if (turn){
OScrn = CreateScreen24(scm,max(dw,h),max(dh,w)) ;
}
else
OScrn = CreateScreen24(scm,max(dw,w),max(dh,h)) ;
/* same size virtual screen */
}
else { /* set up for cropping */
if ((cropw>w) || (cropw < 32)) cropw=dw; /* limit width */
if ((croph>h) || (croph < 20)) croph=dh; /* default to center if bad*/
if ( (cropx < 0) || (cropy <0 ) || (cropx>w) || (croph>h) ) {
/* invalid or unspecified values */
cropx=(w-cropw)/2; /* center */
cropy=(h-croph)/2; /* a normal 736x480 is disp if numbers bad */
}
OScrn = CreateScreen24(scm,cropw,croph);
/* create just for disp to test higher mode */
}
if ( !OScrn){
printf( "Can't Alloc Opal Screen, Try a smaller area \n");
}
/* create the virtual screen to plop the data in */
return(OScrn);
}
int VirtOpal(int asy, char *fname) /* fill display and save OV */
{ /* virtual memory ONLY size 4&up(1536x1024 or 3072x2048
May 7, 1993
THIS IS USED INSTEAD OF DoOpal and TurnOpal. It reads back the raw data
32 lines at a time and does final conversion and puts them in Opal screen */
int a,maxy,nrep,dw,dh,i;
long Err;
register int x,y,yi;
byte *rgbuf[4],*lb1,*lb2,*op1,*np1,*up1,*op2,*np2,*up2; /* pointers into array */
FILE *fpl,*fp1,*fp2; /* pointers to three files */
struct ifhdr hl,h1,h2; /* header data */
planealloc(&Luma ,w,VLINES);/* make some mini Planes to reload parts */
planealloc(&Chroma1,w,VLINES+4);/* should be 150 or 300K */
planealloc(&Chroma2,w,VLINES+4);/* a little xtra in chroma for rollover */
lb1=malloc(w); /* small buffers for shuffling lines in interp */
lb2=malloc(w); /* each = width for long lines */
if ( !lb2) cleanup(E_MEM); /* not enuf mem, need only check second one */
maxy=h;
if(crop) maxy=cropy+croph+VLINES-1; /* only get what we need but entire sector */
if (maxy>h) maxy=h; /* but no more than picture */
nrep = maxy/VLINES; /* number of times we pull in */
fpl=fopen(lumfn,"r"); /* try to open all our files */
fp1=fopen(c1fn,"r");
fp2=fopen(c2fn,"r");
if (!fp1 || !fp2 || !fpl) { /* couldn't open */
printf(" Unable to open one or more intermediate file(s) \n");
cleanup(E_READ); }
fread(&hl,16,1,fpl); /* get header data. we MAY actually use this someday!*/
fread(&h1,16,1,fp1);
fread(&h2,16,1,fp2);
rgbuf[0]=Luma.im; /* set buffer pointer for conversion to to opal*/
rgbuf[1]=Chroma1.im;
rgbuf[2]=Chroma2.im;
/* assume the Opal Screen is already made */
if (!OScrn) cleanup(E_OVD); /* but check to make sure */
dw= OScrn->Width; /* get these from Opal Screen structure */
dh= OScrn->Height;
/* below here updated for each pic, so loop on this ! */
telltime("Starting file readback. Time so far=",clock1);
for(i=0;i<nrep;i++) { /* take a 300K hunk of data and move it in */
fread(Luma.im,w,VLINES,fpl); /* read in a hunk of data,64 lines */
if ( w>2000) { /* handle chroma differently for Mode 5 */
if (i==0) { /* first set of lines */
a=fread(Chroma1.im,w/2,(VLINES/2)+1,fp1); /* one xtra line f/interp */
a=fread(Chroma2.im,w/2,(VLINES/2)+1,fp2); }
else {/* WE NEED ONE MORE LINE SO WE CAN INTERPOLATE LINE # VLINES-1!*/
memcpy(Chroma1.im,lb1,w/2); /* copy the top line last time is bottom */
memcpy(Chroma2.im,lb2,w/2); /* need this for seamless interp */
a=fread(Chroma1.im+(w/2),w/2,(VLINES/2),fp1); /* read the rest from HD */
a=fread(Chroma2.im+(w/2),w/2,(VLINES/2),fp2); /* half width half ht*/
}
memcpy(lb1,Chroma1.im+((w*VLINES)/4),w/2); /* get raw last line */
memcpy(lb2,Chroma2.im+((w*VLINES)/4),w/2); /* becomes first line now */
if (a< (VLINES/2)-1) cleanup(E_READ); /* we could not read all data */
yi=(VLINES/2)+1; /*count lines backward starting with extra line */
for(y=0;y<((VLINES/2)+1);y++){ /* do our interp, move& stretch lines */
yi--; /* start from bottom near END */
op1=Chroma1.im+(( yi+1)*w/2)-1;/* old pointer 1/2 way */
np1=Chroma1.im+(yi*w*2)+w-2 ; /* destination pointer */
op2=Chroma2.im+(( yi+1)*w/2)-1 ;/* old pointer 1/2 way */
np2=Chroma2.im+(yi*w*2)+w-2 ; /* destination pointer */
/* go DOWN in x, DOWN in Y. Don't paint ourselfs in a corner */
*np1=*(np1+1)=*op1; /* set end points equal */
*np2=*(np2+1)=*op2;
for(x=1;x<(w/2);x++){/* do this #of times of current width */
op1--; np1-=2; op2--; np2-=2; /* drop old ptr by 1 and new by 2 */
*np1=*op1; *np2=*op2; /* set the even point equal */
/* *(np1+1)=*op1; *(np2+1)=*op2; */ /* dont interp */
np1[1]=(((short)op1[0])+((short) op1[1]))>>1;
np2[1]=(((short)op2[0])+((short) op2[1]))>>1; /*
this point and next point in X direction */
} /* try sub divede by 2 with >>1 */
}
for(y=0;y<(VLINES+2);y+=2){ /* this reads between the lines */
op1=Chroma1.im + (y*w);/* op=linebelow up=line above*/
np1=op1+w; up1=np1+w; /* set pointers one finished line apart */
op2=Chroma2.im + (y*w);
np2=op2+w; up2=np2+w; /* set pointers one finished line apart */
for(x=0;x<w;x++){ /* set odd lines by reading between even lines */
*(np1++)=(((int)*(op1++))+((int)*(up1++)))>>1;
*(np2++)=(((int)*(op2++))+((int)*(up2++)))>>1;
/* the missing lines are the avg of lines above&below*/
}
} /* close for Y loop */
} /* close w>2000 loop */
else{ /* for modes 4,6 we have all bytes */
a=fread(Chroma1.im,w,VLINES,fp1);
a= fread(Chroma2.im,w,VLINES,fp2);
if (a<VLINES) cleanup(E_READ); /* we could not read all data */
}
if ( !(i&7) ) printf("\n"); /* lf every 8 numbers */
printf("%d ",i*VLINES);
ycctorgb(w,VLINES,&Luma,&Chroma1,&Chroma2); /* convert it to RGB */
RGBtoOV( OScrn,rgbuf,-1*cropx,(-1*cropy)+ (i*VLINES),w,VLINES); /* convert it */
}
printf ( " \n");
telltime("Time to do all virtual processing ",clock1);
fclose(fpl); /* close all files */
fclose(fp1);
fclose(fp2);
remove(lumfn); remove(c1fn); remove(c2fn); /* remove temp files */
free(lb1); free(lb2);/* let go of buffers we dont need them anymore */
/* copy the data into the virtual screen */
AutoSync24(asy);
Err = (long)LowMemUpdate24 (OScrn,0);
if ((Err>OL_ERR_MAXERR) && (!(OScrn->Flags&ILACE24)))
{ AutoSync24 (asy);
/* Err = (long)LowMemUpdate24 (OScrn,6); */
}
if ( (OScrn) && (fname) ){ /* we can save file */
if (jpeg)
a=SaveJPEG24(OScrn,fname,NULL, jpeg);
else
a=SaveIFF24(OScrn,fname, NULL,NULL);
if (a) printf( "iff save error # %d couldn't save picture\n",a);
else printf( "file saved as %s \n",fname);
}
if (Err < OL_ERR_MAXERR)
{ CloseScreen24 ();
if (Err==OL_ERR_OUTOFMEM)
printf ("Out of memory!! \n");
else if (Err==OL_ERR_CANTCLOSE)
printf("OpalVision Display in Use.\n");
else
printf("Error Displaying image!! \n");
cleanup(E_OVD);
}
OVPriority();
Delay(10);
while ( *Button &0x040) { /* button for single show */
Delay(10); }
if ( backdrop){ /* we want to leave image as backdrop */
AmigaPriority ();
DualDisplay24 ();
Delay (2L);
LatchDisplay24 (TRUE);
Delay (2L);
}
AmigaPriority();
SingleDisplay24();
FreeScreen24 (OScrn);
CloseScreen24();
return(0);
}
int DoOpal(int asy,int slide, char *fname) /* fill display and save OV */
{
int a,dw,dh,pic,slerr,orun;
UBYTE *rgbp[4];
long Err;
/* assume the Opal Screen is already made */
if (!OScrn) cleanup(E_OVD); /* but check to make sure */
pic=1; slerr=0; orun=1; /* init variables */
dw= OScrn->Width; /* get these from Opal Screen structure */
dh= OScrn->Height;
if (slide) pic= pstart; /* don't start at zero */
/* below here updated for each pic, so loop on this ! */
while (orun && (pic < 150)) { /* keep doing this */
rgbp[0]= Luma.im; /* set image area pointers */
rgbp[1]= Chroma1.im;
rgbp[2]= Chroma2.im;
TurnOpal(OScrn,rgbp,cropx,cropy,dw,dh,turn); /* turn it */
telltime("Picture loading & Decoding took",clock1);
/* copy the data into the virtual screen */
AutoSync24(asy);
Err = (long)LowMemUpdate24 (OScrn,0);
if ((Err>OL_ERR_MAXERR) && (!(OScrn->Flags&ILACE24)))
{ AutoSync24 (asy);
/* Err = (long)LowMemUpdate24 (OScrn,6); */
}
if ( (OScrn) && (fname) ){ /* we can save file */
if (jpeg)
a=SaveJPEG24(OScrn,fname,NULL, jpeg);
else
a=SaveIFF24(OScrn,fname, NULL,NULL);
if (a) printf( "iff save error # %d couldn't save picture\n",a);
else printf( "file saved as %s \n",fname);
}
if (Err < OL_ERR_MAXERR)
{ CloseScreen24 ();
if (Err==OL_ERR_OUTOFMEM)
printf ("Out of memory!! \n");
else if (Err==OL_ERR_CANTCLOSE)
printf("OpalVision Display in Use.\n");
else
printf("Error Displaying image!! \n");
cleanup(E_OVD);
}
pic++;
if (slide ) {
slerr=GetNextPic(pic,0);
if (slerr ==9){
printf("we hit last pic. Starting over\n");
pic=1; Delay(60); /* go back and start over */
slerr=GetNextPic(pic,0);
}
if(slerr) orun=0; /* get the next file, if error,quit */
/* FadeOut24(25);*/
}
else orun=0;
OVPriority();
Delay(10);
if ( !(*Button & 0x040)) { /* button down for SLIDE */
Delay(30); /* debounse */
if (!(*Button & 0x040 )) orun=0; /* get out, is held down */
}
}
while ((*Button &0x040) && !(slide)){ /* button for single show */
Delay(10); }
if ( backdrop){ /* we want to leave image as backdrop */
AmigaPriority ();
DualDisplay24 ();
Delay (2L);
LatchDisplay24 (TRUE);
Delay (2L);
}
FreeScreen24 (OScrn);
CloseScreen24();
return(0);
}
int GetNextPic(int pic,int res) /* slidesow, get next picture to OV */
{
static char *fn="CD0:PHOTO_CD/IMAGES/IMG0001.PCD";
int i,wm,ht;
if(fin) fclose(fin); /* if it is open, close it */
fin=NULL;
if((pic>199) || (pic<0)) return(999); /* pic too high */
wm=w/192; /* use to switch */
ht= (pic/100); /* convert to digits */
pic -= ht * 100; /* get it to 100 */
*(fn+24)= h+48;
*(fn+25)=(pic/10)+48;
*(fn+26)=(pic%10)+48;
printf("filename is %s\n",fn);
fin=fopen(fn,"r");
if(!fin) return(9);
switch(wm) { /* based on resolution */
case 2 : SEEK(L_Head+L_Base16+1); break;
case 4 : SEEK(L_Head+L_Base16+L_Base4+1) ; break;
case 1 : SEEK(L_Head+1); break;
default: return(13);
}
Luma.iwidth=Luma.iheight=0;
Chroma1.iwidth=Chroma1.iheight=0;
Chroma2.iwidth=Chroma2.iheight=0;
i=readplain(w,h,&Luma,&Chroma1,&Chroma2);
if (fin) { fclose(fin); fin=NULL; }
/* printf( "plane read %d w %d h %d i \n",w,h,i); */
if(i) return(i); /* an error here break */
interpolate(&Chroma1);
interpolate(&Chroma2);
ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
return(0); /* successful */
}
int TurnOpal( Oscr, rgbp, xos,yos,dw,dh,dir)
struct OpalScreen *Oscr;
UBYTE *rgbp[3]; /* pointers for decoded Photo CD data */
int xos,yos,dw,dh,dir; /* offset and size of image, and dir 0=no 1=r else l
do cropping here, if unable to open screen, stash in file and
reload down the line */
{ /* this is to view images on edge. To save memory we only buffer
16 lines */
long size,lines;
int i,j,ystep;
UBYTE *buf,*rgbuf[3],*rp,*gp,*bp; /* pointers into array */
lines=16;
size=h*3*lines; /* well do 16 lines (initially columns ) at a time */
buf=malloc(size); /* try to allocate the memory */
rp=rgbuf[0]=buf;
gp=rgbuf[1]=buf+(h*lines);/* set pointer */
bp=rgbuf[2]=buf+(h*lines*2);
if ( !buf) {
printf("can't allocate turn buffer, try closing some windows \n");
cleanup(E_MEM);
}
if (crop) { xos *= -1; /* invert since pcd larger than Opal */
yos *= -1;
}
if ( dir==0) {
RGBtoOV ( OScrn,rgbp,xos,yos,w,h );
return(3); /* do this step here */
}
if (turn==1) { /* right turn */
/* start from bottom left j=column turned to row */
for(j=0; j<w; j++){
for(i=h-1; i>=0; i--) { /* count up from bottom build one line*/
ystep=(i*w)+j;
*rp++=*(rgbp[0]+ ystep); /* copy pixels for each color */
*gp++=*(rgbp[1]+ ystep);
*bp++=*(rgbp[2]+ ystep);
}
if( ( ( j& 0x0F )==0x0f) || (j == w-1)) { /* update ea 16 lines*/
rp=rgbuf[0]; /* eset pointers to bases */
gp=rgbuf[1];
bp=rgbuf[2];
RGBtoOV( Oscr,rgbuf,xos,yos+j-lines+1,h,lines); /* convert it */
}
}
}
else { /* left turn */
/* start from bottom left j=column turned to row */
for(j=w-1; j>=0; j--){
for(i=0; i<h; i++) { /* count down build one line*/
ystep=(i*w)+j;
*rp++=*(rgbp[0]+ ystep); /* copy pixels for each color */
*gp++=*(rgbp[1]+ ystep);
*bp++=*(rgbp[2]+ ystep);
}
if( ( j& 0x0F )==0x00) { /* update ea 16 lines*/
rp=rgbuf[0]; /* reset pointers to bases */
gp=rgbuf[1];
bp=rgbuf[2];
RGBtoOV( Oscr,rgbuf,xos,yos+w-j-lines,h,lines); /* convert it */
}
}
}
free(buf); /* let it go, we dont need it anymore */
return(j);
}
int storeplane(implane *imp,char *fn)
{ /* store a plane in a file, return 0 if OK, else error */
FILE *fps;
int a;
fps = fopen(fn,"w"); /* open it */
if (!fps) return(1); /* error if not open */
a=fwrite( &ih,16,1,fps); /* write header, use default */
a=fwrite( imp->im,imp->iwidth,imp->iheight,fps);
fclose(fps); /* close the file no matter what */
if ( a < imp->iheight) return (a+1);
return(0); /* we are successful */
}
enum ERRORS readplain(w,h,l,c1,c2)
dim w,h;
implane *l,*c1,*c2;
{
dim i;
byte *pl=0,*pc1=0,*pc2=0;
if(l)
{ if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) cleanup(E_INTERN);
l->iwidth=w;
l->iheight=h;
pl=l->im;
}
if(c1)
{ if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) cleanup(E_INTERN);
c1->iwidth=w/2; /* Make sure theyre big enough */
c1->iheight=h/2;
pc1=c1->im;
}
if(c2)
{ if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) cleanup(E_INTERN);
c2->iwidth=w/2;
c2->iheight=h/2;
pc2=c2->im;
}
for(i=0;i<h/2;i++)
{
if(pl)
{
if(fread(pl,w,1,fin)<1) return(E_READ);
pl+= l->mwidth;
if(fread(pl,w,1,fin)<1) return(E_READ);
pl+= l->mwidth;
}
else SKIPr(2*w);
if(pc1)
{ if(fread(pc1,w/2,1,fin)<1) return(E_READ);
pc1+= c1->mwidth;
}
else SKIPr(w/2);
if(pc2)
{ if(fread(pc2,w/2,1,fin)<1) return(E_READ);
pc2+= c2->mwidth;
}
else SKIPr(w/2);
}
#ifdef DEBUG
fprintf(stderr,"R-Position %x\n",ftell(fin));
#endif
return E_NONE;
}
static void interpolate(implane *p)
{
dim w,h,x,y,yi,h2,w2;
byte *optr,*nptr,*uptr;
if ((!p) || (!p->im)) cleanup(E_INTERN);
w=p->iwidth;
h=p->iheight;
if(p->mwidth < 2*w ) cleanup(E_INTERN);
if(p->mheight < 2*h ) cleanup(E_INTERN);
w2=p->iwidth =2*w;
h2=p->iheight=2*h;/* cut some multiplications by doing once at start */
for(y=0;y<h;y++) /* each line */
{yi=h-1-y; /* start from bottom near END */
optr=p->im+ yi*p->mwidth + (w-1);/* old pointer USES MAX WID starts 1/2 way*/
nptr=p->im+((yi*p->mwidth)<<1) + (w2 - 2); /* starts near end and works back*/
nptr[0]=nptr[1]=optr[0]; /* set these two end points to oldpoint*/
for(x=1;x<w;x++)/* do this #of times of current width */
{ optr--; nptr-=2; /* drop old ptr by 1 and new by 2 */
nptr[0]=optr[0]; /* set the even point equal */
nptr[1]=(((short)optr[0])+((short)optr[1]))>>1; /* odd pt is avg between
this point and next point in X direction */
} /* try sub divede by 2 with >>1 */ }
for(y=0;y<h-1;y++) /* this reads between the lines */
{optr=p->im + ((y*p->mwidth)<<1);
nptr=optr+p->mwidth;
uptr=nptr+p->mwidth;
for(x=0;x<w2;x++)
*(nptr++)=(((short)*(optr++))+((short)*(uptr++)))>>1;
}
bcopy(p->im + (h2-2)*p->mwidth, p->im + (h2-1)*p->mwidth, w2);
}
void telltime(tmsg, clock1) /* tell elapsed time, array at start is passed */
unsigned int clock1[2];
char *tmsg;
{
unsigned int x;
double t;
x=timer(clock2); /* get time I came out of it */
if( clock2[1] < clock1[1]) { /* take care of uS rollover */
clock2[1]+= 1000000L;
clock2[0]--; }
clock2[1]-=clock1[1]; /* get diff in us */
clock2[0]-=clock1[0];
t=(double) (clock2[1]/1000000.0) +(double)clock2[0];
printf( "%s %8.3f Sec. \n",tmsg,t);
}
static void ycctorgb(w,h,l,c1,c2)
dim w,h;
implane *l,*c1,*c2;
{
register dim x,y,i;
register byte *pl,*pc1,*pc2;
short red,green,blue;
float L;
static int init=0;
static float XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
/*
if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) cleanup(E_INTERN);
if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) cleanup(E_INTERN);
if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) cleanup(E_INTERN);
*/
if(do_sharp) sharpit(l);
if(!init)
{init=1;
for(i=0;i<256;i++)
{ XL[i]=1.3584 * ((float)i );
XC1[i]=2.2179 * (((float)i)-156.0);
XC2[i]=1.8215 * (((float)i)-137.0);
XC1g[i]= -0.194 * XC1[i];
XC2g[i]= -0.509 * XC2[i];
}
}
for(y=0;y<h;y++)
{
pl = l->im + y * l->mwidth;
pc1= c1->im + y * c1->mwidth;
pc2= c2->im + y * c2->mwidth;
for(x=0;x<w;x++)
{
L = XL[*pl];
red =L + XC2[*pc2];
green=L + XC1g[*pc1] + XC2g[*pc2];
blue =L + XC1[*pc1];
NORM(red);
NORM(green);
NORM(blue);
*(pl++ )=red;
*(pc1++)=/*green */ green;
*(pc2++)=blue;
}
/* printf("line %d raw is %d %d %d \n",y,*pl,*pc1,*pc2); */
}
}
static void druckeid()
{
struct ph1 *d;
char ss[100];
SEEK(1);
if(READBUF<1) cleanup(E_READ);
d=(struct ph1 *)sbuffer;
#define dr(feld,kennung) \
strncpy(ss,feld,sizeof(feld));\
ss[sizeof(feld)]=0;\
fprintf(stderr,"%s: %s \n",kennung,ss);
dr(d->id1,"Id1")
dr(d->id2,"Id2")
dr(d->id3,"Id3")
dr(d->id4,"Id4")
dr(d->id5,"Id5")
#undef dr
}
struct pcdword
{ byte high,low;
};
struct pcdquad { byte len,highseq,lowseq,key;}; /* size=4 */
struct pcdhqt { byte entries; struct pcdquad entry[256];}; /* size=1025*/
struct myhqt { unsigned long seq,mask,len; byte key; }; /* size=13 */
#define E ((unsigned long) 1)
static void readhqtsub(source,ziel,anzahl)
struct pcdhqt *source;
struct myhqt *ziel;
int *anzahl;
{int i;
struct pcdquad *sub;
struct myhqt *help;
*anzahl=source->entries+1;
for(i=0;i<*anzahl;i++)
{sub= source->entry+i;
help=ziel+i;
help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
help->len = ((unsigned long) sub->len) +1;
if(help->len > 16) cleanup(E_HUFF);
help->key = sub->key;
help->mask = ~ ( (E << (32-help->len)) -1);
}
#ifdef DEBUG
for(i=0;i<*anzahl;i++)
{help=ziel+i;
fprintf(stderr,"H: %3d %08lx & %08lx (%2d) = %02x = %5d %8x\n",
i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
help->seq & (~help->mask));
}
#endif
}
static struct myhqt myhuffl[256],myhuff1[256],myhuff2[256];
static int myhufflenl=0,myhufflen1=0,myhufflen2=0;
static void readhqt(w,h,n)
dim w,h,n;
{
byte *ptr; /* fix type to placate compiler 3-6-93 */
int a;
if ( n==3 ) { /* if for decompressing highest get 2 sectors */
a=fread(sbuffer,1,4000,fin); }
else a=READBUF; /* else, for second highest, get only 1 sector */
if(a ==0 ) cleanup(E_READ);
ptr = sbuffer;
readhqtsub((struct pcdhqt *) ptr,myhuffl,&myhufflenl);
if(n<2) return;
ptr+= 4* myhufflenl;
ptr++;
readhqtsub((struct pcdhqt *) ptr,myhuff1,&myhufflen1);
if(n<3) return;
ptr+= 4* myhufflen1;
ptr++;
readhqtsub((struct pcdhqt *) ptr,myhuff2,&myhufflen2);
/* printf( " Length of hqts %d\n",ptr-sbuffer); */
}
#define nextbuf { nptr=sbuffer; if(READBUF < 1) cleanup(E_READ);\
}
#define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
#define shiftout(n){ sreg<<=n; inh-=n; \
while (inh<=24) \
{checkbuf; \
sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
inh+=8;\
}\
}
/* I think the following routine is screwed since it works OK up to
its usage 3/8/93 readhqt not called anymire */
static void decompress(w,h,f,f1,f2)
dim w,h;
implane *f,*f1,*f2;
{
register int i,htlen,sum;
unsigned long sreg,maxwidth;
unsigned int inh,n,zeile,segment,ident,j;
struct myhqt *htptr,*hp;
byte *nptr;
byte *lptr;
/* try bypass this so we can decompress Chroma only */
/*
if((!f) || (!f->im)) cleanup(E_INTERN);
if((f->iheight < h) || (f->iwidth<w)) cleanup(E_INTERN); */
maxwidth=f->mwidth;
if (!f) maxwidth=w;
sreg=0x0000;
nextbuf;
inh=32;
lptr=0;
shiftout(16);
shiftout(16);
n=0;
for(;;) /* keeps going and going*/
{
if((sreg & 0xffffff00) == 0xfffffe00)
{shiftout(24);
ident=sreg>>16;
shiftout(16);
zeile=(ident>>1) & 0x1fff;
segment=ident>>14;
/* the loop passes here about once each line */
/* if (!( zeile & 127)) /* do each 16th line */
fprintf(stderr,"Ident %4x Zeile: %6d Segment %3d Pixels bisher: %d\n",
ident,zeile,segment,n);*/
if(lptr && (n!=maxwidth)) cleanup(E_SEQ1);
n=0;
/* zeile must mean height in pixel rows */
if(zeile==h) return; /* WERE DONE */
if(zeile > h) cleanup(E_SEQ2);
switch(segment)
{
case 0: htlen=myhufflenl;
htptr=myhuffl;
if(!f ){ /* do this if luma not used */
lptr=NULL;
maxwidth=w;
} /* to placate things */
else {
lptr=f->im + zeile*f->mwidth; /* set pointer */
maxwidth=f->iwidth;
}
break;
case 2: if(!f1) return; /* were doing MONOCHROME only */
if ( virt && f && f1) { /* size 5, virtual mode
and have NOT done a chroma hunk yet we need to do some stuff*/
ih.width=w; ih.height=h; /* Luma plane is FULL size*/
j= storeplane(f,lumfn);
planefree(&Luma); /* free it up */
f=0L; /* set luma plane to 0, we dont need it anymore */
if (j) { printf("Error %d storing Luma file, too little disk space? \n",j);
cleanup(E_WRITE); }
ih.width=w/2; ih.height=h/2; /* chroma planes 1/4 size*/
planealloc(f1,w/2,h/2); /* just do max detail1536x1024*/
planealloc(f2,w/2,h/2); /* these two take about 3Meg*/
for( j=0; j< 256; j++) { /* align lines to max width to conform */
memcpy(f1->im+(j*w/2),C1t.im+(384*j),384); /* copy temps over */
memcpy(f2->im+(j*w/2),C2t.im+(384*j),384); /* copy temps over */
} /* space the 384x256 chroma to be interpolated */
planefree(&C1t); /* get rid of temp chroma */
planefree(&C2t);
printf("Interpolating chroma \n");
f1->iheight=f2->iheight=h/8; /* only 368x256*/
f1->iwidth =f2->iwidth =w/8;
interpolate(f1);
interpolate(f1);
interpolate(f2);
interpolate(f2); /* NOW interpolate it out x4 each dir*/
printf("really Starting to decompress Chroma\n");
/* we are all ready to go */
/* BTW f=Luma, f1=Chroma1 and f2=Chroma2 planes */
}
if (!f1->im) cleanup(E_SEQ7); /* cover allocation errors */
lptr=f1->im + (zeile>>1)*f1->mwidth;
maxwidth=f1->iwidth;
htlen=myhufflen1;
htptr=myhuff1;
break;
case 3: if(!f2) cleanup(E_SEQ7);
if(!f2->im) cleanup(E_SEQ7);
lptr=f2->im + (zeile>>1)*f2->mwidth;
maxwidth=f2->iwidth;
htlen=myhufflen2;
htptr=myhuff2;
if(zeile >= (h-9)) return; /* break off a little early */
/* TEMP FIX FOR BUG IN SYSTEM READ OF LAST SECTOR.
CHROMA RESOLUTION SLIGHTLY LOWER ON BOTTOM 4 LINES */
break;
default:cleanup(E_SEQ3);
} /* end of segment case statement */
}
else
{ /* DECOMPRESS THE PIXEL */
if(n>maxwidth)/* cleanup(E_SEQ4);*/
{printf("Nonfatal err4 line %d seg %d \n",zeile,segment); return; }
for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
if(i>=htlen) cleanup(E_SEQ5);
if (lptr) { /* if we are not saving, skip this much */
sum=((int)(*lptr)) + ((int)hp->key);
/* add decompressed data to pixel */
*(lptr++) = sum & 0xff ;
/* ---THIS SEEMS TO HAVE FIXED THE PROBLEM,
BAZZ 3-10-93! CHANGING NORM TO & 0XFF ; */
n++;
}
shiftout(hp->len);
} /* END OF ELSE ROUTINE */
} /* END OF FOR(;;) INDEFINATE LOOP */
} /* END OF DECOMPRESS SUBROUTINE */
static void clear(l,n)
implane *l;
int n;
{ dim x,y;
byte *ptr;
/* l->iwidth=l->mwidth;
l->iheight=l->mheight;
*/
ptr=l->im;
for (x=0;x<l->mwidth;x++)
for (y=0; y<l->mheight;y++)
*(ptr++)=n;
}
static void sharpit(l)
implane *l;
{int x,y,h,w,mw,akk;
byte f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
if((!l) || (!l->im)) cleanup(E_INTERN);
if(l->iwidth > slen) cleanup(E_INTERN);
old=f1; akt=f2;
h=l->iheight;
w=l->iwidth;
mw=l->mwidth;
for(y=1;y<h-1;y++)
{
ptr=l->im+ y*mw;
optr=ptr-mw;
work=akt;
*(work++)= *(ptr++);
for(x=1;x<w-1;x++)
{ akk = 5*((int)ptr[0])- ((int)ptr[1]) - ((int)ptr[-1])
- ((int)ptr[mw]) - ((int)ptr[-mw]);
NORM(akk);
*(work++)=akk;
ptr++;
}
*(work++)= *(ptr++);
if(y>1) bcopy(old,optr,w);
help=old;old=akt;akt=help;
}
bcopy(old,optr+mw,w);
}
int Display_Mode_Check (void)
{ /* see if we are in high res */
struct MonitorInfo MonitorInfo;
DisplayInfoHandle Handle;
ULONG ModeID;
LONG Result;
GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library",36L);
if (GfxBase==NULL) return (TRUE);
IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library",0L);
if (IntuitionBase==NULL)
{ CloseLibrary ((struct Library *)GfxBase);
return (TRUE);
}
ModeID = GetVPModeID (&IntuitionBase->FirstScreen->ViewPort);
Handle = FindDisplayInfo (ModeID);
Result = GetDisplayInfoData (Handle,(UBYTE *)&MonitorInfo,
sizeof (struct MonitorInfo),DTAG_MNTR,NULL);
/* If line frequency if >15Khz, a backdrop
* cannot be displayed.
*/
if (MonitorInfo.TotalColorClocks<220)
{ CloseLibrary ((struct Library *)GfxBase);
CloseLibrary ((struct Library *)IntuitionBase);
return (FALSE);
}
CloseLibrary ((struct Library *)GfxBase);
CloseLibrary ((struct Library *)IntuitionBase);
return (TRUE);
}